NDVI and Wildfires¶

The effects of global warming are felt everywhere. While it is hard to quantify or compare exactly all of the effects, one of the most extreme we have been seeing is the increase of wildfires in the western US. Wildfires frequency has not just been increasing, but the severity of these burns has also been increasing. According to this NASA visualization, wildfire burned area has been increasing. This is made worse due to the increased drought stress caused by increasing temperatures.

While drought has many different definitions depending on who is talking about it, it is generally recognized as a lack of moisture in the environment causing stress. Drought can be hard to identify, but much research has been done on this topic. One method that has been developed to create a more robust system to identify drought utilizes NDVI. You can read more about this method here.

In order to get a glimpse into this relationship, I am going to use the Waldo Canyon Fire as an area of study. The Waldo Canyon fire ignited June 23rd, 2012 and burned approximately 20,000 acres before being contained. It burned parts of El Paso and Teller counties, near Pikes Peak. According to historical united states drought data, the region began seeing drought conditions September 2010 and fluxuated between abnormal dryness and extreme drought well past the fire. Lets look at NDVI leading up to this event to get an idea at what it looks like before a fire.

Everything beyond this point is going to be code. If you are not interested in that, skip to the bottom to view the results of the analysis.

woody_smoke_plume_downsized.png Image taken from my childhood backyard before evacuation

In [1]:
# Import packages
import geopandas as gpd # For working with shapefiles
import pathlib # For working with filesystem
import hvplot.xarray # For dynamic plotting
import hvplot.pandas # For dynamic plotting
import matplotlib.pyplot as plt # For plotting
import earthpy.api.appeears as eaapp # For working with AppEEARS API
import earthpy # For working with spatial data
import os # For working with filesystem
import xarray as xr # For working with raster data
import rioxarray as rxr # For working with spatial raster data
import pandas as pd # For working with layered arrays
import datetime # For converting julian day to standard date time

Step 1: Get Data¶

First, we need to access the fire boundary. A great source for fire areas in the United States is MTBS. You can download an entire fire data package for any reported wildfire burned in the US. This is where I am going to source my Waldo Canyon Fire shapefile from. Move the .zip file into your data directory of choice. I recommend unzipping the file and renaming it, as it comes very nested and not with a very workable name.

In [2]:
# Define our filepaths
BASE_DATA_PATH = pathlib.Path.cwd().parent / "data"
os.makedirs(BASE_DATA_PATH, exist_ok=True)
# Define filepath for shapefile (this needs to be done seperate due to lack of python support from MTBS)
FIRE_SHAPEFILE_PATH = BASE_DATA_PATH / "waldo_canyon_burn_package/co3888410493320120623_20100918_20130926_burn_bndy.shp"
# Create earthpy project for downloading NDVI data.
project = earthpy.Project("Waldo Canyon Fire Vegetation", dirname = "waldo_canyon_fire")
In [3]:
# Read in the shapefile
fire_bounds = gpd.read_file(FIRE_SHAPEFILE_PATH).to_crs(crs="EPSG:4326")
# Check to make sure it looks right
fire_bounds.hvplot(
    geo=True, tiles='EsriImagery', 
    frame_width=500,
    legend=False, fill_color=None, edge_color='white',
    # This parameter makes all the column values in the dataset visible.
    hover_cols='all')
WARNING:param.main: edge_color option not found for polygons plot with bokeh; similar options include: ['muted_color', 'bgcolor', 'line_color']
Out[3]:

Now that the shapefile is loaded in, we need to download the NDVI data.

In [4]:
# Initialize AppeearsDownloader for MODIS NDVI data
ndvi_downloader = eaapp.AppeearsDownloader(
    download_key="waldo_canyon_ndvi",
    project=project,
    product='MOD13Q1.061',
    layer='_250m_16_days_NDVI',
    start_date="07-01",
    end_date="07-31",
    recurring=True,
    year_range=[2007, 2013], 
    polygon=fire_bounds
)
In [5]:
ndvi_downloader.download_files(cache=True)
Out[5]:
<generator object Path.rglob at 0x168104260>

Step 2: Wrangle the Data¶

Now that we have all the data we need, we need to get in into a workable format. This involves sorting through all of the .tif files downloaded, and storing them into a DataArray alongside the date of the file.

In [6]:
# Get a sorted list of NDVI tif file paths
ndvi_paths = sorted(list(project.project_dir.rglob('*NDVI*.tif')))

# Display the first and last three files paths to check the pattern
ndvi_paths[:3], ndvi_paths[-3:]
Out[6]:
([PosixPath('/Users/keingtobin/Library/Application Support/earth-analytics/waldo_canyon_fire/waldo_canyon_ndvi/MOD13Q1.061_2007167_to_2013212/MOD13Q1.061__250m_16_days_NDVI_doy2007177000000_aid0001.tif'),
  PosixPath('/Users/keingtobin/Library/Application Support/earth-analytics/waldo_canyon_fire/waldo_canyon_ndvi/MOD13Q1.061_2007167_to_2013212/MOD13Q1.061__250m_16_days_NDVI_doy2007193000000_aid0001.tif'),
  PosixPath('/Users/keingtobin/Library/Application Support/earth-analytics/waldo_canyon_fire/waldo_canyon_ndvi/MOD13Q1.061_2007167_to_2013212/MOD13Q1.061__250m_16_days_NDVI_doy2007209000000_aid0001.tif')],
 [PosixPath('/Users/keingtobin/Library/Application Support/earth-analytics/waldo_canyon_fire/waldo_canyon_ndvi/MOD13Q1.061_2007167_to_2013212/MOD13Q1.061__250m_16_days_NDVI_doy2013177000000_aid0001.tif'),
  PosixPath('/Users/keingtobin/Library/Application Support/earth-analytics/waldo_canyon_fire/waldo_canyon_ndvi/MOD13Q1.061_2007167_to_2013212/MOD13Q1.061__250m_16_days_NDVI_doy2013193000000_aid0001.tif'),
  PosixPath('/Users/keingtobin/Library/Application Support/earth-analytics/waldo_canyon_fire/waldo_canyon_ndvi/MOD13Q1.061_2007167_to_2013212/MOD13Q1.061__250m_16_days_NDVI_doy2013209000000_aid0001.tif')])
In [7]:
doy_start = -25
doy_end = -18


# Loop through each NDVI image
ndvi_das = []
for ndvi_path in ndvi_paths:
    # Get date from file name
    date = str(ndvi_path)[doy_start:doy_end]
    # Convert date string to datetime object
    date = datetime.datetime.strptime(date, '%Y%j')
    # Open dataset
    da = rxr.open_rasterio(ndvi_path, mask_and_scale=True).squeeze()
    # Add date dimension and clean up metadata
    da = da.assign_coords({'date': date})
    da = da.expand_dims({'date': 1})
    da.name = 'NDVI'

    # Prepare for concatenation
    ndvi_das.append(da)
In [8]:
# Combine NDVI images from all dates
combined_ndvi_da = xr.combine_by_coords(ndvi_das, coords=['date'])
combined_ndvi_da
/var/folders/0y/hhqlb7w5069fz86snbnctjcr0000gn/T/ipykernel_74756/1663403724.py:2: FutureWarning: In a future version of xarray the default value for compat will change from compat='no_conflicts' to compat='override'. This is likely to lead to different results when combining overlapping variables with the same name. To opt in to new defaults and get rid of these warnings now use `set_options(use_new_combine_kwarg_defaults=True) or set compat explicitly.
  combined_ndvi_da = xr.combine_by_coords(ndvi_das, coords=['date'])
/var/folders/0y/hhqlb7w5069fz86snbnctjcr0000gn/T/ipykernel_74756/1663403724.py:2: FutureWarning: In a future version of xarray the default value for compat will change from compat='no_conflicts' to compat='override'. This is likely to lead to different results when combining overlapping variables with the same name. To opt in to new defaults and get rid of these warnings now use `set_options(use_new_combine_kwarg_defaults=True) or set compat explicitly.
  combined_ndvi_da = xr.combine_by_coords(ndvi_das, coords=['date'])
Out[8]:
<xarray.Dataset> Size: 335kB
Dimensions:      (date: 21, y: 53, x: 75)
Coordinates:
    band         int64 8B 1
  * x            (x) float64 600B -105.0 -105.0 -105.0 ... -104.9 -104.9 -104.9
  * y            (y) float64 424B 38.98 38.98 38.98 38.98 ... 38.88 38.88 38.87
    spatial_ref  int64 8B 0
  * date         (date) datetime64[ns] 168B 2007-06-26 2007-07-12 ... 2013-07-28
Data variables:
    NDVI         (date, y, x) float32 334kB 0.692 0.692 0.692 ... 0.381 0.381
xarray.Dataset
    • date: 21
    • y: 53
    • x: 75
    • band
      ()
      int64
      1
      array(1)
    • x
      (x)
      float64
      -105.0 -105.0 ... -104.9 -104.9
      array([-105.015625, -105.013542, -105.011458, -105.009375, -105.007292,
             -105.005208, -105.003125, -105.001042, -104.998958, -104.996875,
             -104.994792, -104.992708, -104.990625, -104.988542, -104.986458,
             -104.984375, -104.982292, -104.980208, -104.978125, -104.976042,
             -104.973958, -104.971875, -104.969792, -104.967708, -104.965625,
             -104.963542, -104.961458, -104.959375, -104.957292, -104.955208,
             -104.953125, -104.951042, -104.948958, -104.946875, -104.944792,
             -104.942708, -104.940625, -104.938542, -104.936458, -104.934375,
             -104.932292, -104.930208, -104.928125, -104.926042, -104.923958,
             -104.921875, -104.919792, -104.917708, -104.915625, -104.913542,
             -104.911458, -104.909375, -104.907292, -104.905208, -104.903125,
             -104.901042, -104.898958, -104.896875, -104.894792, -104.892708,
             -104.890625, -104.888542, -104.886458, -104.884375, -104.882292,
             -104.880208, -104.878125, -104.876042, -104.873958, -104.871875,
             -104.869792, -104.867708, -104.865625, -104.863542, -104.861458])
    • y
      (y)
      float64
      38.98 38.98 38.98 ... 38.88 38.87
      array([38.982292, 38.980208, 38.978125, 38.976042, 38.973958, 38.971875,
             38.969792, 38.967708, 38.965625, 38.963542, 38.961458, 38.959375,
             38.957292, 38.955208, 38.953125, 38.951042, 38.948958, 38.946875,
             38.944792, 38.942708, 38.940625, 38.938542, 38.936458, 38.934375,
             38.932292, 38.930208, 38.928125, 38.926042, 38.923958, 38.921875,
             38.919792, 38.917708, 38.915625, 38.913542, 38.911458, 38.909375,
             38.907292, 38.905208, 38.903125, 38.901042, 38.898958, 38.896875,
             38.894792, 38.892708, 38.890625, 38.888542, 38.886458, 38.884375,
             38.882292, 38.880208, 38.878125, 38.876042, 38.873958])
    • spatial_ref
      ()
      int64
      0
      crs_wkt :
      GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
      semi_major_axis :
      6378137.0
      semi_minor_axis :
      6356752.314245179
      inverse_flattening :
      298.257223563
      reference_ellipsoid_name :
      WGS 84
      longitude_of_prime_meridian :
      0.0
      prime_meridian_name :
      Greenwich
      geographic_crs_name :
      WGS 84
      horizontal_datum_name :
      World Geodetic System 1984
      grid_mapping_name :
      latitude_longitude
      spatial_ref :
      GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
      GeoTransform :
      -105.01666665690055 0.002083333333139592 0.0 38.983333329708046 0.0 -0.002083333333139592
      array(0)
    • date
      (date)
      datetime64[ns]
      2007-06-26 ... 2013-07-28
      array(['2007-06-26T00:00:00.000000000', '2007-07-12T00:00:00.000000000',
             '2007-07-28T00:00:00.000000000', '2008-06-25T00:00:00.000000000',
             '2008-07-11T00:00:00.000000000', '2008-07-27T00:00:00.000000000',
             '2009-06-26T00:00:00.000000000', '2009-07-12T00:00:00.000000000',
             '2009-07-28T00:00:00.000000000', '2010-06-26T00:00:00.000000000',
             '2010-07-12T00:00:00.000000000', '2010-07-28T00:00:00.000000000',
             '2011-06-26T00:00:00.000000000', '2011-07-12T00:00:00.000000000',
             '2011-07-28T00:00:00.000000000', '2012-06-25T00:00:00.000000000',
             '2012-07-11T00:00:00.000000000', '2012-07-27T00:00:00.000000000',
             '2013-06-26T00:00:00.000000000', '2013-07-12T00:00:00.000000000',
             '2013-07-28T00:00:00.000000000'], dtype='datetime64[ns]')
    • NDVI
      (date, y, x)
      float32
      0.692 0.692 0.692 ... 0.381 0.381
      units :
      NDVI
      AREA_OR_POINT :
      Area
      array([[[0.692     , 0.692     , 0.692     , ..., 0.57089996,
               0.57089996, 0.55619997],
              [0.6545    , 0.6545    , 0.6527    , ..., 0.401     ,
               0.401     , 0.491     ],
              [0.6554    , 0.6624    , 0.6684    , ..., 0.331     ,
               0.3849    , 0.48349997],
              ...,
              [0.6658    , 0.6622    , 0.6622    , ..., 0.471     ,
               0.52849996, 0.55799997],
              [0.6705    , 0.6767    , 0.6852    , ..., 0.46409997,
               0.4495    , 0.48139998],
              [0.6821    , 0.6821    , 0.6821    , ..., 0.36409998,
               0.3852    , 0.3852    ]],
      
             [[0.6221    , 0.6221    , 0.6849    , ..., 0.5617    ,
               0.5617    , 0.5489    ],
              [0.5724    , 0.5724    , 0.5965    , ..., 0.3238    ,
               0.3238    , 0.5286    ],
              [0.5736    , 0.5736    , 0.5924    , ..., 0.45929998,
               0.39749998, 0.48279998],
      ...
              [0.66099995, 0.65669996, 0.6525    , ..., 0.4657    ,
               0.5008    , 0.575     ],
              [0.7369    , 0.65669996, 0.6525    , ..., 0.44259998,
               0.4014    , 0.43379998],
              [0.7369    , 0.6577    , 0.6577    , ..., 0.2943    ,
               0.32479998, 0.32479998]],
      
             [[0.5036    , 0.5036    , 0.5263    , ..., 0.5847    ,
               0.5847    , 0.5625    ],
              [0.5331    , 0.5331    , 0.5263    , ..., 0.3918    ,
               0.3918    , 0.4854    ],
              [0.5177    , 0.5331    , 0.5244    , ..., 0.2532    ,
               0.39609998, 0.44579998],
              ...,
              [0.6587    , 0.62      , 0.5767    , ..., 0.4779    ,
               0.5358    , 0.5358    ],
              [0.70699996, 0.70699996, 0.6464    , ..., 0.4779    ,
               0.46499997, 0.4985    ],
              [0.5832    , 0.61469996, 0.61469996, ..., 0.3265    ,
               0.38099998, 0.38099998]]], shape=(21, 53, 75), dtype=float32)
    • x
      PandasIndex
      PandasIndex(Index([-105.01562499023399, -105.01354165690086, -105.01145832356771,
             -105.00937499023456, -105.00729165690143,  -105.0052083235683,
             -105.00312499023515,   -105.001041656902, -104.99895832356887,
             -104.99687499023574, -104.99479165690259, -104.99270832356945,
             -104.99062499023631, -104.98854165690318, -104.98645832357003,
             -104.98437499023689, -104.98229165690375, -104.98020832357062,
             -104.97812499023748, -104.97604165690433,  -104.9739583235712,
             -104.97187499023806, -104.96979165690492, -104.96770832357177,
             -104.96562499023864,  -104.9635416569055, -104.96145832357236,
             -104.95937499023921, -104.95729165690608, -104.95520832357295,
              -104.9531249902398, -104.95104165690665, -104.94895832357352,
             -104.94687499024039, -104.94479165690724,  -104.9427083235741,
             -104.94062499024096, -104.93854165690783, -104.93645832357468,
             -104.93437499024154,  -104.9322916569084, -104.93020832357527,
             -104.92812499024213, -104.92604165690898, -104.92395832357585,
             -104.92187499024271, -104.91979165690957, -104.91770832357642,
             -104.91562499024329, -104.91354165691016, -104.91145832357701,
             -104.90937499024386, -104.90729165691073,  -104.9052083235776,
             -104.90312499024445,  -104.9010416569113, -104.89895832357817,
             -104.89687499024504, -104.89479165691189, -104.89270832357874,
             -104.89062499024561, -104.88854165691248, -104.88645832357933,
             -104.88437499024619, -104.88229165691305, -104.88020832357992,
             -104.87812499024677, -104.87604165691363,  -104.8739583235805,
             -104.87187499024736, -104.86979165691422, -104.86770832358107,
             -104.86562499024794,  -104.8635416569148, -104.86145832358166],
            dtype='float64', name='x'))
    • y
      PandasIndex
      PandasIndex(Index([ 38.98229166304148,  38.98020832970834,   38.9781249963752,
              38.97604166304206,  38.97395832970892,  38.97187499637578,
              38.96979166304264,   38.9677083297095,  38.96562499637636,
              38.96354166304322, 38.961458329710084, 38.959374996376944,
             38.957291663043804, 38.955208329710665, 38.953124996377525,
             38.951041663044386, 38.948958329711246,  38.94687499637811,
              38.94479166304497,  38.94270832971183,  38.94062499637869,
              38.93854166304555,  38.93645832971241,  38.93437499637927,
              38.93229166304613,  38.93020832971299,  38.92812499637985,
              38.92604166304671,  38.92395832971357,  38.92187499638043,
              38.91979166304729,  38.91770832971415,  38.91562499638101,
              38.91354166304787,  38.91145832971473, 38.909374996381594,
             38.907291663048454, 38.905208329715315, 38.903124996382175,
             38.901041663049035, 38.898958329715896, 38.896874996382756,
              38.89479166304962,  38.89270832971648,  38.89062499638334,
               38.8885416630502,  38.88645832971706,  38.88437499638392,
              38.88229166305078,  38.88020832971764,   38.8781249963845,
              38.87604166305136,  38.87395832971822],
            dtype='float64', name='y'))
    • date
      PandasIndex
      PandasIndex(DatetimeIndex(['2007-06-26', '2007-07-12', '2007-07-28', '2008-06-25',
                     '2008-07-11', '2008-07-27', '2009-06-26', '2009-07-12',
                     '2009-07-28', '2010-06-26', '2010-07-12', '2010-07-28',
                     '2011-06-26', '2011-07-12', '2011-07-28', '2012-06-25',
                     '2012-07-11', '2012-07-27', '2013-06-26', '2013-07-12',
                     '2013-07-28'],
                    dtype='datetime64[ns]', name='date', freq=None))

Step 3: Analysis¶

Now we can use this data to preform different types of analysis.

In [9]:
# Clip the NDVI data to only be inside the fire boundary
fire_clip = combined_ndvi_da.rio.clip(fire_bounds.geometry, from_disk=True)
fire_clip
Out[9]:
<xarray.Dataset> Size: 314kB
Dimensions:      (x: 73, y: 51, date: 21)
Coordinates:
    band         int64 8B 1
  * x            (x) float64 584B -105.0 -105.0 -105.0 ... -104.9 -104.9 -104.9
  * y            (y) float64 408B 38.98 38.98 38.98 38.97 ... 38.88 38.88 38.88
  * date         (date) datetime64[ns] 168B 2007-06-26 2007-07-12 ... 2013-07-28
    spatial_ref  int64 8B 0
Data variables:
    NDVI         (date, y, x) float32 313kB 0.6545 0.6527 nan ... nan nan nan
xarray.Dataset
    • x: 73
    • y: 51
    • date: 21
    • band
      ()
      int64
      1
      array(1)
    • x
      (x)
      float64
      -105.0 -105.0 ... -104.9 -104.9
      axis :
      X
      long_name :
      longitude
      standard_name :
      longitude
      units :
      degrees_east
      array([-105.013542, -105.011458, -105.009375, -105.007292, -105.005208,
             -105.003125, -105.001042, -104.998958, -104.996875, -104.994792,
             -104.992708, -104.990625, -104.988542, -104.986458, -104.984375,
             -104.982292, -104.980208, -104.978125, -104.976042, -104.973958,
             -104.971875, -104.969792, -104.967708, -104.965625, -104.963542,
             -104.961458, -104.959375, -104.957292, -104.955208, -104.953125,
             -104.951042, -104.948958, -104.946875, -104.944792, -104.942708,
             -104.940625, -104.938542, -104.936458, -104.934375, -104.932292,
             -104.930208, -104.928125, -104.926042, -104.923958, -104.921875,
             -104.919792, -104.917708, -104.915625, -104.913542, -104.911458,
             -104.909375, -104.907292, -104.905208, -104.903125, -104.901042,
             -104.898958, -104.896875, -104.894792, -104.892708, -104.890625,
             -104.888542, -104.886458, -104.884375, -104.882292, -104.880208,
             -104.878125, -104.876042, -104.873958, -104.871875, -104.869792,
             -104.867708, -104.865625, -104.863542])
    • y
      (y)
      float64
      38.98 38.98 38.98 ... 38.88 38.88
      axis :
      Y
      long_name :
      latitude
      standard_name :
      latitude
      units :
      degrees_north
      array([38.980208, 38.978125, 38.976042, 38.973958, 38.971875, 38.969792,
             38.967708, 38.965625, 38.963542, 38.961458, 38.959375, 38.957292,
             38.955208, 38.953125, 38.951042, 38.948958, 38.946875, 38.944792,
             38.942708, 38.940625, 38.938542, 38.936458, 38.934375, 38.932292,
             38.930208, 38.928125, 38.926042, 38.923958, 38.921875, 38.919792,
             38.917708, 38.915625, 38.913542, 38.911458, 38.909375, 38.907292,
             38.905208, 38.903125, 38.901042, 38.898958, 38.896875, 38.894792,
             38.892708, 38.890625, 38.888542, 38.886458, 38.884375, 38.882292,
             38.880208, 38.878125, 38.876042])
    • date
      (date)
      datetime64[ns]
      2007-06-26 ... 2013-07-28
      array(['2007-06-26T00:00:00.000000000', '2007-07-12T00:00:00.000000000',
             '2007-07-28T00:00:00.000000000', '2008-06-25T00:00:00.000000000',
             '2008-07-11T00:00:00.000000000', '2008-07-27T00:00:00.000000000',
             '2009-06-26T00:00:00.000000000', '2009-07-12T00:00:00.000000000',
             '2009-07-28T00:00:00.000000000', '2010-06-26T00:00:00.000000000',
             '2010-07-12T00:00:00.000000000', '2010-07-28T00:00:00.000000000',
             '2011-06-26T00:00:00.000000000', '2011-07-12T00:00:00.000000000',
             '2011-07-28T00:00:00.000000000', '2012-06-25T00:00:00.000000000',
             '2012-07-11T00:00:00.000000000', '2012-07-27T00:00:00.000000000',
             '2013-06-26T00:00:00.000000000', '2013-07-12T00:00:00.000000000',
             '2013-07-28T00:00:00.000000000'], dtype='datetime64[ns]')
    • spatial_ref
      ()
      int64
      0
      crs_wkt :
      GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
      semi_major_axis :
      6378137.0
      semi_minor_axis :
      6356752.314245179
      inverse_flattening :
      298.257223563
      reference_ellipsoid_name :
      WGS 84
      longitude_of_prime_meridian :
      0.0
      prime_meridian_name :
      Greenwich
      geographic_crs_name :
      WGS 84
      horizontal_datum_name :
      World Geodetic System 1984
      grid_mapping_name :
      latitude_longitude
      spatial_ref :
      GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
      GeoTransform :
      -105.01458332356742 0.002083333333139592 0.0 38.98124999637491 0.0 -0.002083333333139592
      array(0)
    • NDVI
      (date, y, x)
      float32
      0.6545 0.6527 nan ... nan nan nan
      units :
      NDVI
      AREA_OR_POINT :
      Area
      array([[[0.6545    , 0.6527    ,        nan, ...,        nan,
                      nan,        nan],
              [0.6624    , 0.6684    ,        nan, ...,        nan,
                      nan,        nan],
              [0.6746    , 0.68439996, 0.6884    , ...,        nan,
                      nan,        nan],
              ...,
              [       nan,        nan,        nan, ...,        nan,
                      nan,        nan],
              [       nan,        nan,        nan, ...,        nan,
                      nan,        nan],
              [       nan,        nan,        nan, ...,        nan,
                      nan,        nan]],
      
             [[0.5724    , 0.5965    ,        nan, ...,        nan,
                      nan,        nan],
              [0.5736    , 0.5924    ,        nan, ...,        nan,
                      nan,        nan],
              [0.59499997, 0.59499997, 0.57879996, ...,        nan,
                      nan,        nan],
      ...
              [       nan,        nan,        nan, ...,        nan,
                      nan,        nan],
              [       nan,        nan,        nan, ...,        nan,
                      nan,        nan],
              [       nan,        nan,        nan, ...,        nan,
                      nan,        nan]],
      
             [[0.5331    , 0.5263    ,        nan, ...,        nan,
                      nan,        nan],
              [0.5331    , 0.5244    ,        nan, ...,        nan,
                      nan,        nan],
              [0.5177    , 0.52639997, 0.484     , ...,        nan,
                      nan,        nan],
              ...,
              [       nan,        nan,        nan, ...,        nan,
                      nan,        nan],
              [       nan,        nan,        nan, ...,        nan,
                      nan,        nan],
              [       nan,        nan,        nan, ...,        nan,
                      nan,        nan]]], shape=(21, 51, 73), dtype=float32)
    • x
      PandasIndex
      PandasIndex(Index([-105.01354165690086, -105.01145832356771, -105.00937499023456,
             -105.00729165690143,  -105.0052083235683, -105.00312499023515,
               -105.001041656902, -104.99895832356887, -104.99687499023574,
             -104.99479165690259, -104.99270832356945, -104.99062499023631,
             -104.98854165690318, -104.98645832357003, -104.98437499023689,
             -104.98229165690375, -104.98020832357062, -104.97812499023748,
             -104.97604165690433,  -104.9739583235712, -104.97187499023806,
             -104.96979165690492, -104.96770832357177, -104.96562499023864,
              -104.9635416569055, -104.96145832357236, -104.95937499023921,
             -104.95729165690608, -104.95520832357295,  -104.9531249902398,
             -104.95104165690665, -104.94895832357352, -104.94687499024039,
             -104.94479165690724,  -104.9427083235741, -104.94062499024096,
             -104.93854165690783, -104.93645832357468, -104.93437499024154,
              -104.9322916569084, -104.93020832357527, -104.92812499024213,
             -104.92604165690898, -104.92395832357585, -104.92187499024271,
             -104.91979165690957, -104.91770832357642, -104.91562499024329,
             -104.91354165691016, -104.91145832357701, -104.90937499024386,
             -104.90729165691073,  -104.9052083235776, -104.90312499024445,
              -104.9010416569113, -104.89895832357817, -104.89687499024504,
             -104.89479165691189, -104.89270832357874, -104.89062499024561,
             -104.88854165691248, -104.88645832357933, -104.88437499024619,
             -104.88229165691305, -104.88020832357992, -104.87812499024677,
             -104.87604165691363,  -104.8739583235805, -104.87187499024736,
             -104.86979165691422, -104.86770832358107, -104.86562499024794,
              -104.8635416569148],
            dtype='float64', name='x'))
    • y
      PandasIndex
      PandasIndex(Index([ 38.98020832970834,   38.9781249963752,  38.97604166304206,
              38.97395832970892,  38.97187499637578,  38.96979166304264,
               38.9677083297095,  38.96562499637636,  38.96354166304322,
             38.961458329710084, 38.959374996376944, 38.957291663043804,
             38.955208329710665, 38.953124996377525, 38.951041663044386,
             38.948958329711246,  38.94687499637811,  38.94479166304497,
              38.94270832971183,  38.94062499637869,  38.93854166304555,
              38.93645832971241,  38.93437499637927,  38.93229166304613,
              38.93020832971299,  38.92812499637985,  38.92604166304671,
              38.92395832971357,  38.92187499638043,  38.91979166304729,
              38.91770832971415,  38.91562499638101,  38.91354166304787,
              38.91145832971473, 38.909374996381594, 38.907291663048454,
             38.905208329715315, 38.903124996382175, 38.901041663049035,
             38.898958329715896, 38.896874996382756,  38.89479166304962,
              38.89270832971648,  38.89062499638334,   38.8885416630502,
              38.88645832971706,  38.88437499638392,  38.88229166305078,
              38.88020832971764,   38.8781249963845,  38.87604166305136],
            dtype='float64', name='y'))
    • date
      PandasIndex
      PandasIndex(DatetimeIndex(['2007-06-26', '2007-07-12', '2007-07-28', '2008-06-25',
                     '2008-07-11', '2008-07-27', '2009-06-26', '2009-07-12',
                     '2009-07-28', '2010-06-26', '2010-07-12', '2010-07-28',
                     '2011-06-26', '2011-07-12', '2011-07-28', '2012-06-25',
                     '2012-07-11', '2012-07-27', '2013-06-26', '2013-07-12',
                     '2013-07-28'],
                    dtype='datetime64[ns]', name='date', freq=None))
In [10]:
# Compute mean annual July NDVI
ndvi_means = (fire_clip # Select inside bounds
                .groupby(fire_clip.date.dt.year) #Group by the date time year
                .mean(...) # Take the mean accross all dimensions
                .NDVI # Select the NDVI variable
                .to_dataframe())['NDVI'] # Convert to dataframe

ndvi_means
Out[10]:
year
2007    0.637241
2008    0.572468
2009    0.628934
2010    0.622582
2011    0.588587
2012    0.389066
2013    0.405215
Name: NDVI, dtype: float32
In [11]:
# Plot a line graph to inspect mean NDVI before and a little bit after the burn
ndvi_means.hvplot(title = "Mean NDVI of Waldo Canyon Burn Scar 2007-2013")
Out[11]:

Results¶

Based on the historical united states drought data provided by drought.gov, there was a period of abnormally dry conditions that covered most of El Paso County, and a small portion of Teller County beginning in Spring 2008. We can see this dip in the plot above, with a lower average NDVI in the area compared to a year without a dry spell. Despite this dry spell continuing into the winter of 2008 and early 2009, the vegetation was able to recover fairly fast, with a NDVI that looks about the same as 2007 (0.637 vs 0.629).

We begin to see a dip in NDVI again between 2010 and 2011, which correlates with a severe drought covering both Teller and El Paso counties beginning in the winter of 2010, and holding until well after the fire burned. Because the fire lit in June 2012, we see a massive dip in NDVI in the area between 2011 and 2012.

In [12]:
# Select a slice of data for 2011 and 2012 so we can map see the map of NDVI
ndvi_before = combined_ndvi_da.sel(date=slice("2011-01-01","2011-12-31"))
ndvi_after = combined_ndvi_da.sel(date=slice("2012-01-01","2022-12-31"))
# Take the mean and only grab the NDVI data
ndvi_before = ndvi_before.mean('date').NDVI
ndvi_after = ndvi_after.mean('date').NDVI
In [13]:
# Plot the NDVI before the fire
(
    ndvi_before.hvplot(x='x', y='y', cmap="PiYG", geo=True,
                    title="Average July NDVI in Waldo Canyon Burn Area \n 2011")
    *
    fire_bounds.hvplot(geo=True, fill_color=None, line_color='black')
)
Out[13]:
In [14]:
# Plot the NDVI after the fire
(
    ndvi_after.hvplot(x='x', y='y', cmap="PiYG", geo=True,
                    title="Average July NDVI In Waldo Canyon Burn Area \n 2012",
                     xlabel="Lon", ylabel="Lat")
    *
    fire_bounds.hvplot(geo=True, fill_color=None, line_color='black')
)
Out[14]:

As we can tell from the two plots above, the fire didn't completely wipe out all vegetation in the burn scar. Some central areas were able to make it out without too severe of burns aswell.

In [15]:
# Calculate the difference
ndvi_diff = ndvi_after - ndvi_before

# Plot the difference
(
    ndvi_diff.hvplot(x='x', y='y', cmap="PiYG", geo=True,
                    title="Difference in NDVI Before and After Burn \n 2011 vs 2012",
                     xlabel="Lon", ylabel="Lat")
    *
    fire_bounds.hvplot(geo=True, fill_color=None, line_color='black')
)
Out[15]:

The above map gives us a good idication of the burn severity within the boundary.

Bonus: Highway 24 Floods 2013¶

As many know, the affects of a wildfire are't just on the vegetation in the area. Often, there are severe affects on environments surrounding the fire. One that was seen in the year following the fire was flash flooding in the Ute Pass corridor of Highway 24. US Highway 24 was actually part of the south-western boundary of the fire, due to the fire not being able to hop the pass. Some videos of the flooding can be found here.

The flash floods were made worse by the fire. This is due to the loss of vegetatation that would have helped slow down the flow of water. There was also a large flux of mud in the flooding, also in part due to the fire the previous year. With the increase of wildfire frequency and severity in the US West due to climate change, we need to find more ways to become resilient to issues like this that arise.